#include <os/diskio.h>
#include <os/task.h>
#include <os/spinlock.h>
#include <os/vmm.h>
#include <os/memcache.h>
#include <os/fatfs.h>
#include <os/fsal.h>
#include <os/diskman.h>
#include <lib/type.h>
#include <sys/ioctl.h>

disk_status_t DiskOpen(uint8_t pydrv)
{
    if (pydrv > DISK_MAX)
        return DSTU_NOINIT;

    // call diskman to open disk solt
    if (diskman.open(pydrv) < 0)
        return DSTU_NODISK;
    return DSTU_OK;
}

disk_status_t DiskClose(uint8_t pydrv)
{
    if (pydrv > DISK_MAX)
        return DSTU_NOINIT;
    if (diskman.close(pydrv) < 0)
        return DSTU_NODISK;
    return DSTU_OK;
}

disk_status_t DiskWrite(uint8_t pdrv, uint8_t *buff, lba_t sec, uint32_t count)
{
    if (pdrv > DISK_MAX)
        return DSTU_NOINIT;

    // KPrint("[diskio] write pdrv %d sectors %d\n", pdrv, sec);
    if (diskman.write(pdrv, sec, buff, count * FS_SEC_MAX) < 0)
        return DSTU_ERROR;
    return DSTU_OK;
}

disk_status_t DiskRead(uint8_t pdrv, uint8_t *buff, lba_t sec, uint32_t count)
{
    if (pdrv > DISK_MAX)
        return DSTU_NOINIT;
    // KPrint("[diskio] read pdrv %d sectors %d\n", pdrv, sec);
    if (diskman.read(pdrv, sec, buff, count * FS_SEC_MAX) < 0)
        return DSTU_ERROR;
    return DSTU_OK;
}

disk_status_t DiskStatus(uint8_t pydrv)
{
    if (pydrv > DISK_MAX)
        return DSTU_NOINIT;
    return 0;
}

disk_status_t DiskIoCtl(uint8_t pdrv, uint32_t cmd, void *arg)
{
    disk_status_t res;

    if (pdrv > DISK_MAX)
        return DSTU_NOINIT;

    switch (cmd)
    {
    case CTRL_SYNC:
        res = DSTU_OK;
        break;
    case GET_SECTOR_SIZE:
    {
        *(uint32_t *)arg = 512;
        res = DSTU_OK;
    }
    case GET_BLOCK_SIZE:
    {
        *(uint32_t *)arg = 1;
        res = DSTU_OK;
    }
    break;
    case GET_SECTOR_COUNT:
        if (diskman.ioctl(pdrv, DISKIO_GETSIZE, arg) < 0)
            res = DSTU_ERROR;
        else
            res = DSTU_OK;
        break;
    default:
        if (diskman.ioctl(pdrv, cmd, arg) < 0)
            res = DSTU_ERROR;
        else
            res = DSTU_OK;
        break;
    }

    return res;
}
